use actix_web::{get, HttpResponse, post, Responder, web};

pub fn router_config(cfg: &mut web::ServiceConfig) {
    cfg.service(hello)
        .service(echo)
        .route("/hey", web::get().to(manual_hello));
}

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[post("/echo")]
async fn echo(req_body: String) -> impl Responder {
    HttpResponse::Ok().body(req_body)
}

async fn manual_hello() -> impl Responder {
    HttpResponse::Ok().body("Hey there!")
}

#[cfg(test)]
mod tests {
    use super::*;
    use actix_web::test;
    use crate::common::test_utils::{init_test_app_with_db, init_test_db, resolve_response};

    #[test]
    async fn test_hello() {
        let db = init_test_db().await;
        let app = init_test_app_with_db(db, |cfg| {
            router_config(cfg);
        }).await;
        let req = test::TestRequest::get().uri("/").to_request();
        let res = test::call_service(&app, req).await;
        let body = resolve_response(res).await;
        assert_eq!("Hello world!", body);
    }

    #[test]
    async fn test_echo() {
        let db = init_test_db().await;
        let app = init_test_app_with_db(db, |cfg| {
            router_config(cfg);
        }).await;
        let req = test::TestRequest::post().uri("/echo").set_payload("asdfasdf").to_request();
        let res = test::call_service(&app, req).await;
        let body = resolve_response(res).await;
        assert_eq!("asdfasdf", body);
    }

    #[test]
    async fn test_manual_hello() {
        let db = init_test_db().await;
        let app = init_test_app_with_db(db, |cfg| {
            router_config(cfg);
        }).await;
        let req = test::TestRequest::get().uri("/hey").to_request();
        let res = test::call_service(&app, req).await;
        let body = resolve_response(res).await;
        assert_eq!("Hey there!", body);
    }
}
